#include "mysql_package.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include "debug_assert.h"
#include "debug_log.h"

#pragma comment(lib, "libmysql")

#define ARRAY_LENGTH(a)  (sizeof(a) / sizeof(a[0]))


bool Mysql_Init(const char *p_host, const int port, const char *p_user, const char *p_passwd, MYSQL **pp_handle) {
	MYSQL *p_handle = NULL;
	MYSQL *p_conn_handle = NULL;

	ASSERT(NULL != p_host && NULL != p_user && NULL != p_passwd && NULL != pp_handle);
	p_handle = mysql_init(NULL);
	if (NULL == p_handle) {
		printf("mysql_init() error=%d,%s\n", mysql_errno(p_handle), mysql_error(p_handle));
		return false;
	}
	else {
		p_handle->reconnect = 1;
		do {
			p_conn_handle = mysql_real_connect(p_handle, p_host, p_user, p_passwd, NULL, port, NULL, 0);	
			LOG("mysql_real_connect() conn_handle=%p, result=%d,%s\n", p_conn_handle, mysql_errno(p_conn_handle), mysql_error(p_conn_handle));
			usleep(1000 * 1000 * 1);
		} 
		while (NULL == p_conn_handle);

		*pp_handle = p_handle;
		return true;			
	}
}

void Mysql_Uninit(const MYSQL *pc_handle) {
	MYSQL *p_handle = (MYSQL *)pc_handle;

	ASSERT(NULL != p_handle);
	mysql_close(p_handle);
}

bool Mysql_HasTable(const MYSQL *pc_handle, const char *p_db_name, const char *p_table_name) {
	MYSQL *p_handle = (MYSQL *)pc_handle;
	MYSQL_RES *p_result = NULL;
	MYSQL_ROW row;
	char sentence[256];
	int query_ret;

	ASSERT(NULL != p_handle && NULL != p_db_name && NULL != p_table_name);
	sprintf(sentence, "USE %s;", p_db_name);
	query_ret = mysql_query(p_handle, sentence);
	if (0 != query_ret) {
		printf("mysql_query() error=%d,%s\n", mysql_errno(p_handle), mysql_error(p_handle));
		return false;
	}
	else {
		sprintf(sentence, "SHOW TABLES LIKE '%s';", p_table_name);
		query_ret = mysql_real_query(p_handle, sentence, strlen(sentence));
		if (0 != query_ret) {
			printf("mysql_query() error=%d,%s\n", mysql_errno(p_handle), mysql_error(p_handle));
			return false;
		}
		else {
			p_result = mysql_store_result(p_handle);
			row = mysql_fetch_row(p_result);
			mysql_free_result(p_result);
			if (NULL == row) 
				return false;
			else 
				return true;
		}
	}
}

bool Mysql_PrintTables(const MYSQL *pc_handle, const char *p_db_name, const char *p_table_name) {
	MYSQL *p_handle = (MYSQL *)pc_handle;
	MYSQL_RES *p_result = NULL;
	MYSQL_ROW row;
	char sentence[256];
	int query_ret;

	ASSERT(NULL != p_handle && NULL != p_db_name && NULL != p_table_name);
	sprintf(sentence, "USE %s;", p_db_name);
	query_ret = mysql_query(p_handle, sentence);
	if (0 != query_ret) {
		printf("mysql_query() error=%d,%s\n", mysql_errno(p_handle), mysql_error(p_handle));
		return false;
	}
	else {
		if (0 == strcmp(p_table_name, ""))
			strcpy(sentence, "SHOW TABLES;");
		else
			sprintf(sentence, "SHOW TABLES LIKE '%s';", p_table_name);
		query_ret = mysql_real_query(p_handle, sentence, strlen(sentence));
		if (0 != query_ret) {
			printf("mysql_query() error=%d,%s\n", mysql_errno(p_handle), mysql_error(p_handle));
			return false;
		}
		else {
			p_result = mysql_store_result(p_handle);
			row = mysql_fetch_row(p_result);
			while (NULL != row) {
				printf("%s\n", row[0]);
				row = mysql_fetch_row(p_result);
			}
			mysql_free_result(p_result);
			return true;
		}
	}
}

bool Mysql_ExecuteFile(const MYSQL *pc_handle, const char *p_file_path) {
	MYSQL *p_handle = (MYSQL *)pc_handle;
	FILE *pf_sql = NULL;
	char *p_find = NULL;
	char line[256];
	char sentence[1024];
	int query_ret;
	bool ok_file;

	ASSERT(NULL != p_handle && NULL != p_file_path);
	pf_sql = fopen(p_file_path, "rb");
	if (NULL == pf_sql) {
		printf("fopen() error! path=%s\n", p_file_path);
		ok_file = false;
	}
	else {
		while (0 == feof(pf_sql) && 0 == ferror(pf_sql)) {
			memset(sentence, 0, sizeof(sentence));
			do {
				fgets(line, sizeof(line), pf_sql);
				if (0 != ferror(pf_sql) || 0 != feof(pf_sql)) {
					break;
				}
				else {
					sprintf(sentence, "%s%s", sentence, line);
					p_find = strchr(sentence, ';');
					continue;
				}
			}
			while (NULL == p_find);

			if (0 == feof(pf_sql) && 0 == ferror(pf_sql)) {
				query_ret = mysql_real_query(p_handle, sentence, strlen(sentence));
				if (0 != query_ret) {
					printf("mysql_query() error=%d,%s\n", mysql_errno(p_handle), mysql_error(p_handle));
					ok_file = false;
					break;
				}
				else {
					ok_file = true;
					continue;
				}
			}
		}
		fclose(pf_sql);
	}

	return ok_file;
}

// 2016-05-16 09:35:28 to 1447443200
static void GetUnixTime(const char *p_intime, int *p_outtime) {
	struct tm tm_time;
	time_t i_time;
	char *p_tok = NULL;
	char tok[64];
	char time[64];
	char year[8], month[8], day[8];
	char hour[8], minute[8], second[8];
	int index;

	ASSERT(NULL != p_intime && NULL != p_outtime);
	ASSERT(strlen(p_intime) < sizeof(time));
	strcpy(time, p_intime);
	index = 0;
	p_tok = strtok(time, "- :");
	while (NULL != p_tok) {
		switch (index) {
			case 0: 
				tm_time.tm_year = atoi(p_tok) - 1900;
				break;
			case 1: 				
				tm_time.tm_mon = atoi(p_tok) - 1;
				break;
			case 2: 				
				tm_time.tm_mday = atoi(p_tok);
				break;
			case 3: 				
				tm_time.tm_hour = atoi(p_tok);
				break;
			case 4: 			
				tm_time.tm_min = atoi(p_tok);
				break;
			case 5: 				
				tm_time.tm_sec = atoi(p_tok);
				break;
			default: 
				break;
		}
		index++;
		p_tok = strtok(NULL, "- :");
	}
	i_time = mktime(&tm_time);
	*p_outtime = i_time;
}

static void ModifyPath(const char *p_path, char *p_modPath, const int modSize) {
	char *p_tok = NULL;
	char tok[256] = {0};

	ASSERT(NULL != p_path && NULL != p_modPath);
	ASSERT(modSize > strlen(p_path));
	strcpy(p_modPath, p_path);
	p_tok = strtok(p_modPath, "\\");
	while (NULL != p_tok) {
		strcat(tok, p_tok);
		strcat(tok, "\\\\");
		p_tok = strtok(NULL, "\\");
	}
	if (NULL != p_tok) {
		ASSERT(modSize > strlen(tok));
		strncpy(p_modPath, tok, strlen(tok) - 2);
		p_modPath[strlen(tok) - 2] = '\0'; 
	}
}


bool Mysql_ReadCategory(const MYSQL *pc_handle, const int catagoryStyle, const int categoryIndex, char *p_categoryName) {
	MYSQL *p_handle = (MYSQL *)pc_handle;
	MYSQL_RES *p_result = NULL;
	MYSQL_ROW row;
	char sentence[1024];
	int startID;
	int endID;
	int query_ret;

	ASSERT(NULL != p_handle && NULL != p_categoryName);
	mysql_query(p_handle, "SET NAMES GBK;");
	query_ret = mysql_query(p_handle, "USE car_phone_server;");
	if (0 != query_ret) {
		printf("mysql_query() error=%d,%s\n", mysql_errno(p_handle), mysql_error(p_handle));
		return false;
	}
	else {
		switch (catagoryStyle) {
			case CATEGORY_LOGO:
				startID = 127;
				endID = 291;
				break;
			case CATEGORY_CHEXI:
				startID = 292;
				endID = 1131;
				break;
			case CATEGORY_CHEXING:
				startID = 1132;
				endID = 3220;
				break;
			case CATEGORY_VIOTYPE:
				startID = 55;
				endID = 64;
				break;
			case CATEGORY_CARTYPE:
				startID = 86;
				endID = 126;
				break;
			case CATEGORY_CARCOLOR:
				startID = 65;
				endID = 76;
				break;
			default:
				startID = 0;
				endID = 0;
				break;
		}
		sprintf(sentence, 
			"SELECT "
			"t_category.c_NAME "
			"FROM "
			"t_category "
			"WHERE "
			"t_category.c_ID BETWEEN %d AND %d AND "
			"t_category.c_INDEX = %d;",
			startID, endID, categoryIndex);
		query_ret = mysql_query(p_handle, sentence);
		if (0 != query_ret) {
			printf("mysql_query() error=%d,%s\n", mysql_errno(p_handle), mysql_error(p_handle));
			return false;
		}
		else {
			p_result = mysql_store_result(p_handle);
			row = mysql_fetch_row(p_result);
			if (NULL != row) {
				strcpy(p_categoryName, row[0]);
				row = mysql_fetch_row(p_result);
			}
			else {
				strcpy(p_categoryName, "δ֪");
			}
			mysql_free_result(p_result);	
			return true;
		}
	}
}


bool Mysql_WriteAlarm(const MYSQL *pc_handle, const t_VioData *p_vio_data) {
	static int index = 0;
	MYSQL *p_handle = (MYSQL *)pc_handle;
	char sentence[1024];
	char extinfo[512];
	int query_ret;

	ASSERT(NULL != p_handle && NULL != p_vio_data);
	mysql_query(p_handle, "SET NAMES UTF8;");
	query_ret = mysql_query(p_handle, "USE car_phone_server;");
	if (0 != query_ret) {
		printf("mysql_query() error=%d,%s\n", mysql_errno(p_handle), mysql_error(p_handle));
		return false;
	}
	else {
		//GetJsonExtInfo(p_vio_data, extinfo, sizeof(extinfo));
		LOG("[vioTime3]%s\n", p_vio_data->m_time);
		strcpy(sentence, "INSERT INTO t_alarm VALUES (");
		sprintf(sentence, 
			"%s'%s', %s, %d, %d, %d, "
			"%d, %d, '%s', '%s', '%s', " 
			"%d, %d, '%s', '%s', '%s', "
			"'%s', '%s', '%s', %d, '%s', "
			"%d, %d, '%s', %d, '%s', "
			"'%s');", 
			sentence, "", p_vio_data->m_time, 0, 0, index, 
			0, 0, "", "", "", 
			0, 0, "", "", "",
			p_vio_data->m_plate, "", "", 0, "",
			0, 0, p_vio_data->m_extinfo, p_vio_data->m_chexing, p_vio_data->m_pic_path,
			""
			);
		LOG("sentence=%s\n", sentence);
		query_ret = mysql_query(p_handle, sentence);
		if (0 != query_ret) {
			LOG("mysql_query() error=%d,%s\n", mysql_errno(p_handle), mysql_error(p_handle));
			return false;
		}
		else {
			index++;
			return true;			
		}
	}	
}		
		
/*
SELECT
t_alarm.c_PHONE,
t_alarm.c_EVENTTIMEMILLIS,
t_alarm.c_DIRECTION,
t_alarm.c_LANEINDEX,
t_alarm.c_VEHICLEINDEX,

t_alarm.c_DEVICEID,
t_alarm.c_OBSERVEDTYPE,
t_alarm.c_IMEI,
t_alarm.c_SIMID,
t_alarm.c_FACE,

t_alarm.c_VEHICLELICENCETYPE,
t_alarm.c_POINTID,
t_alarm.c_ALARMDEVICES,
t_alarm.c_OTHERPICTURES,
t_alarm.c_PICURL,

t_alarm.c_VEHICLELICENSE,
t_alarm.c_PICTUREURLBASE,
t_alarm.c_PLATEPICTURES,
t_alarm.c_VEHICLEPLATECOLOR,
t_alarm.c_PERSONPICTURE,


t_alarm.c_VEHICLESIZE,
t_alarm.c_VIOLATIONONE,
t_alarm.c_EXTINFO,
t_alarm.c_VEHICLETYPE,
t_alarm.c_EVIDENCEPICTURENAMES,
t_alarm.c_VEHICLEEVENT
FROM
t_alarm		

INSERT INTO t_alarm VALUES (
'', 20160602, 0, 0, 0, 
0, 0, 'a', 'b', 'c', 
1, 2, 'h', 'i', 'j', 
'k', 'l', 'm', 11, 'o', 
12, 13, 'p', 14, 'q', 15);
*/	

#if 0
#include "server_config.h"
int main(void) {
	t_VioData vio_data;
	MYSQL *p_handle = NULL;
	char config_path[256];
	char mysql_host[32];
	int mysql_port;
	
	GetConfigPath(config_path, sizeof(config_path));
	GetMysqlHost(config_path, mysql_host, sizeof(mysql_host));
	GetMysqlPort(config_path, &mysql_port);
	bool ok_init = Mysql_Init(mysql_host, mysql_port, "uploader", "uploader", &p_handle);
	printf("Mysql_Init() ret=%d, host=%s, port=%d\n", ok_init, mysql_host, mysql_port);
	InitVioData(&vio_data);
	bool ok_write = Mysql_WriteAlarm(p_handle, &vio_data);
	printf("Mysql_WriteAlarm() ret = %d\n", ok_write);
	Mysql_Uninit(p_handle);

	return 0;
}
#endif

